/*************************************************
 * 描述：分组代理模型
 *
 * File：cxigroupproxy.h
 * Author：zhangzhiming@mozihealthcare.cn
 * Date：25-10-10
 * Update：
 * ************************************************/

#ifndef CXIGROUPPROXY_H
#define CXIGROUPPROXY_H

#include <QAbstractProxyModel>
#include <controls/table/head.h>


class CxiGroupProxy : public QAbstractProxyModel
{
	Q_OBJECT

public:
	explicit CxiGroupProxy(QObject* parent = nullptr);

	~CxiGroupProxy();

	/**
	 * 设置分组列集合，分组时按照传入的顺序进行分组
	 * @param configs
	 */
	void addGroupConfigs(const QList<cxitable::GroupConfig>& configs);

	/**
	 * 添加分组列
	 * @param config
	 */
	void addGroupConfig(const cxitable::GroupConfig& config);

	/**
	 * 移除分组列
	 * @param config
	 */
	void removeGroupConfig(const cxitable::GroupConfig& config);

	/**
	 * 移除分组列
	 * @param column
	 */
	void removeGroupColumn(int column);

	/**
	 * 批量移除分组列
	 * @param columns
	 */
	void removeGroupColumns(const QList<int>& columns);

	/**
	 * 获取分组列
	 * @return
	 */
	QVector<int> groupColumns() const;

	/**
	 * 获取分组列配置
	 * @return
	 */
	QList<cxitable::GroupConfig> groupConfigs() const;

	/**
	 * 刷新分组信息
	 */
	void flushGroup();


	// 重写代理模型方法
	QModelIndex index(int row, int column, const QModelIndex& parent) const override;

	QVariant data(const QModelIndex& index, int role) const override;

	bool setData(const QModelIndex& index, const QVariant& value, int role) override;

	QModelIndex mapFromSource(const QModelIndex& sourceIndex) const override;

	QModelIndex mapToSource(const QModelIndex& proxyIndex) const override;

	void setSourceModel(QAbstractItemModel* sourceModel) override;

	QModelIndex parent(const QModelIndex& child) const override;

	QVariant headerData(int section, Qt::Orientation orientation, int role) const override;

	bool setHeaderData(int section, Qt::Orientation orientation, const QVariant& value, int role) override;

	int rowCount(const QModelIndex& parent) const override;

	int columnCount(const QModelIndex& parent) const override;

private:
	/**
	 * 分组数据
	 */
	struct GroupData
	{
		enum GroupType
		{
			None = 0,// 未定义
			RootGroup = 1,// 根组
			SubGroup = 2,// 子组
			LeafGroup = 3// 叶子组
		};

		QVector<int> sourceRows;// 源行
		QString groupName;// 分组名
		QVector<GroupData*> subGroups;// 子分组
		int level = -1;// 组级
		int column = -1;// 分组列
		GroupType type = None;// 分组类型
		GroupData* parent = nullptr;// 父节点

		~GroupData()
		{
			qDeleteAll(subGroups);
			subGroups.clear();
			parent = nullptr;
		}
	};


	/**
	* 刷新分组信息
	*/
	void rebuildGroups();

	/**
	 * 递归构造节点信息
	 * @param groupData
	 * @param level
	 * @param endRow
	 */
	void buildGroupsRecursive(GroupData* groupData, int level, int endRow);

	/**
	 * 判断分组配置中是否包含指定列
	 * @param column
	 * @return
	 */
	bool hasGroupColumn(int column) const;

	/**
	 * 查找分组指定列在分组列表中的索引
	 * @param column
	 * @return
	 */
	int findGroupIndex(int column) const;

	/**
	 * 分组标题内容填充
	 * @param config
	 * @param title
	 * @param data
	 * @param count
	 * @return
	 */
	static QString formatGroupTitle(const cxitable::GroupConfig& config, const QString& title, const QString& data, int count);

	/// 分组信息列表
	QVector<GroupData*> m_groups;
	/// 分组列配置
	QList<cxitable::GroupConfig> m_groupConfigs;
};


#endif//CXIGROUPPROXY_H